package com.ts.controller;

import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import com.ts.entity.MonitorEntity;
import com.ts.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;

import java.io.*;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;

@Slf4j
public class FileTransferClient {

    private static String FORWARD_SLASH = "/";

    //服务器文件切片总数，在此功能，同时会在服务器上面切片
    private static String SPLIT_COUNT = "split";

    //服务器文件切片下载
    private static String LOWERTOUPPER = "lowerToUpper";

    //上位机给下位机传文件
    private static String UPPERTOLOWER = "upperToLower";

    //切片合并
    private static String MERGE = "merge";

    //服务器资源举例

    public static void main(String args[]) throws URISyntaxException{
//        MonitorEntity monitor = new MonitorEntity();
//        monitor.setIp("192.168.1.100");
//        monitor.setPort(8765);
//        monitor.setUpperSendLowerFileName("abcef.mp4");
//        monitor.setAbsUpperFolderPath("D:\\");
//        monitor.setLowerReceiveUpperFileName("abc177.mp4");
//        monitor.setAbsLowerFolderPath("D:\\lidq\\temp\\relative");
//        uploadTest(monitor);

        //上位机接收文件
        MonitorEntity monitorEntity = new MonitorEntity();
        monitorEntity.setIp("192.168.1.100");
        monitorEntity.setPort(8765);
        monitorEntity.setLowerSendUpperFileName("abc177.mp4");
        monitorEntity.setAbsLowerFolderPath("D:\\lidq\\temp\\relative");
        monitorEntity.setUpperReceiveLowerFileName("17ab.mp4");
        monitorEntity.setAbsUpperFolderPath("D:\\2019ABC");
        downloadTest(monitorEntity);

    }

    /**
     *
     * @param monitor
     */
    public static void downloadTest(MonitorEntity monitor) throws URISyntaxException {

        String urlPre = "http://" + monitor.getIp() + ":" + monitor.getPort()+"/";
        String source = monitor.getLowerSendUpperFileName();
        String absUpperFolderPath = monitor.getAbsUpperFolderPath();
        HttpClient httpClient = new DefaultHttpClient();
        //获取切片数
        int splitCount = 0;
        String upperMonitorInfo = JSONObject.toJSONString(monitor);
        List<NameValuePair> list = new LinkedList<>();
        BasicNameValuePair param1 = new BasicNameValuePair("upperMonitorInfo", upperMonitorInfo);
        list.add(param1);

        URIBuilder splitCountUriBuilder = new URIBuilder(urlPre + SPLIT_COUNT);
        splitCountUriBuilder.setParameters(list);
        HttpGet splitCountHttpGet = new HttpGet(splitCountUriBuilder.build());
        try {
            HttpResponse execute = httpClient.execute(splitCountHttpGet);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(execute.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String line = "";
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }
            bufferedReader.close();
            splitCount = Integer.valueOf(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        //读取切片
        for (int i = 0; i < splitCount; i++) {
            String splitReceiveURL = urlPre + FORWARD_SLASH + LOWERTOUPPER + FORWARD_SLASH + i;//"http://localhost:8765/download/ccc.mp4/" + i;
            URIBuilder splitUriBuilder = new URIBuilder(splitReceiveURL);
            splitUriBuilder.setParameters(list);
            HttpGet httpGetSplitReceive =  new HttpGet(splitUriBuilder.build());
            try {
                HttpResponse execute = httpClient.execute(httpGetSplitReceive);
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(execute.getEntity().getContent()));
                StringBuffer sb = new StringBuffer("");
                String line = "";
                String NL = System.getProperty("line.separator");
                while ((line = bufferedReader.readLine()) != null) {
                    sb.append(line + NL);
                }
                bufferedReader.close();
                String content = sb.toString();
                byte[] bytes = Base64.decode(content);
                File folder = new File(absUpperFolderPath);
                if(!folder.exists()){
                    folder.mkdirs();
                }
                FileOutputStream out = new FileOutputStream(folder +"\\"+ source.split("\\.")[0] + "_" + i + ".tmp");
                out.write(bytes);
                out.flush();
                out.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        monitor.setCount(splitCount);
        FileUtil.merge(monitor);
    }

    /**
     *
     * @param monitorEntity     WebService 基础地址
     */
    public static void uploadTest(MonitorEntity monitorEntity){
        //需要上传文件
        String upperSendLowerFileName = monitorEntity.getAbsUpperFolderPath() + File.separator + monitorEntity.getUpperSendLowerFileName();

        //上位机切片临时文件夹
        String cutTempFolder = monitorEntity.getAbsUpperFolderPath() + File.separator + "temp";

        //下位机webservice地址
        String urlPre = "http://" + monitorEntity.getIp() + ":" + monitorEntity.getPort() + "/";

        //下位机路径
        String path = monitorEntity.getAbsLowerFolderPath();

        //切片大小
        int size = monitorEntity.getSize();

        File cutTempFolderFolder = new File(cutTempFolder);
        if(!cutTempFolderFolder.exists()){
            cutTempFolderFolder.mkdirs();
        }

        File file = new File(upperSendLowerFileName);
        String preFileName = file.getName().split("\\.")[0];
        int count = 0;
        try {
            //参数类型：需要上传得到文件，临时切割的文件，切割大小
            count = FileUtil.getSplitFile(file,size,cutTempFolder);
            File folder = new File(cutTempFolder);
            if(folder.isDirectory()){
                File[] files = folder.listFiles();
                for(int i=0;i<files.length;i++){
                    if(files[i].getName().startsWith(preFileName)){
                        File tempFile = files[i];
                        InputStream inputStream = new FileInputStream(tempFile);
                        byte[] bytes = new byte[(int) tempFile.length()];
                        int offset = 0;
                        int numRead = 0;
                        while (offset < bytes.length&& (numRead = inputStream.read(bytes, offset, bytes.length - offset)) >= 0) {
                            offset += numRead;
                        }
                        inputStream.close();
                        String encodedFileString  = Base64.encode(bytes);
                        HttpClient httpClient = new DefaultHttpClient();
                        // 设置超时时间
                        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000);
                        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000);
                        HttpPost post = null;
                        post = new HttpPost(urlPre + UPPERTOLOWER);
                        post.setHeader("Content-type", "application/json; charset=utf-8");
                        post.setHeader("Connection", "Close");

                        MonitorEntity entityMonitor = new MonitorEntity();
                        entityMonitor.setAbsLowerFolderPath(monitorEntity.getAbsLowerFolderPath());
                        entityMonitor.setContent(encodedFileString);
                        entityMonitor.setSplitFileName(tempFile.getName());
                        StringEntity entity = new StringEntity(JSONObject.toJSONString(entityMonitor), Charset.forName("UTF-8"));
                        entity.setContentEncoding("UTF-8");
                        entity.setContentType("application/json");
                        post.setEntity(entity);
                        httpClient.execute(post);
                    }
                }
            }
            HttpClient httpClient = new DefaultHttpClient();

            //切片数目
            //切片所在下位机位置
            //文件名称
            monitorEntity.setCount(count);
            String transferEntityInfo = JSONObject.toJSONString(monitorEntity);
            URIBuilder uriBuilder = new URIBuilder(urlPre + MERGE);
            List<NameValuePair> list = new LinkedList<>();
            BasicNameValuePair param1 = new BasicNameValuePair("transferEntityInfo", transferEntityInfo);
            list.add(param1);
            uriBuilder.setParameters(list);
            HttpGet httpGet = new HttpGet( uriBuilder.build());
            httpClient.execute(httpGet);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }
}
